package com.example.cloud.service.basic.info.impl;

import com.example.cloud.dao.basic.info.ProductRepository;
import com.example.cloud.dao.mongdb.basic.config.MongoUnitRepository;
import com.example.cloud.dao.mongdb.basic.info.MongoCategoryRepository;
import com.example.cloud.dao.mongdb.basic.info.MongoProductRepository;
import com.example.cloud.model.basic.Category;
import com.example.cloud.model.basic.Product;
import com.example.cloud.model.config.Unit;
import com.example.cloud.model.dto.Result;
import com.example.cloud.model.dto.SearchModel;
import com.example.cloud.model.system.User;
import com.example.cloud.service.basic.info.ProductService;
import com.example.cloud.utils.BusinessUtil;
import com.example.cloud.utils.RequestUtil;
import com.example.cloud.utils.ResultUtil;
import org.apache.log4j.Logger;
import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.SQLReady;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by wangtao on 2018/6/6.
 */
@Service
public class ProductServiceImpl implements ProductService {

    private static final Logger logger = Logger.getLogger(ProductServiceImpl.class);

    @PersistenceContext
    EntityManager em;

    @Autowired
    SQLManager sqlManager;

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    private ProductRepository productRepository;

    @Autowired
    private MongoProductRepository mongoProductRepository;

    @Autowired
    private MongoCategoryRepository mongoCategoryRepository;

    @Autowired
    private MongoUnitRepository mongoUnitRepository;

    @Override
    @Transactional
    public void doSave(Product record) {
        // 新增
        if (record.getId() == null) {
            User loginUser = RequestUtil.getLoginUser();
            record.setUserId(loginUser.getId());
            record.setAccountId(loginUser.getAccountId());
            record.setOrganId(loginUser.getOrganId());
            record.setOrganName(loginUser.getOrganName());
        }
        if (record.getBigClassId() != null) {
            Category category = mongoCategoryRepository.findOne(record.getBigClassId());
            if (category != null) {
                record.setBigClassName(category.getName());
            }
        }
        if (record.getSmallClassId() != null) {
            Category category = mongoCategoryRepository.findOne(record.getSmallClassId());
            if (category != null) {
                record.setSmallClassName(category.getName());
            }
        }
        if (record.getUnitId() != null) {
            Unit unit = mongoUnitRepository.findOne(record.getUnitId());
            if (unit != null) {
                record.setUnitName(unit.getName());
            }
        }
        BusinessUtil.appendRecord(record);
        // 物理保存
        productRepository.save(record);
        // 同步缓存
        mongoProductRepository.save(record);
    }

    @Override
    @Transactional
    public void doDelete(List<Long> ids) {
        // 逻辑删除
        StringBuilder sql = new StringBuilder("update basic_product set delete_flag = 1 where id in(:ids)");
        Query query = em.createNativeQuery(sql.toString());
        query.setParameter("ids", ids);
        query.executeUpdate();
        // 删除缓存
        mongoProductRepository.deleteByIdIn(ids);
    }

    @Override
    public void loadCache() {
        List<Product> list = productRepository.findAll();
        if (!list.isEmpty()) {
            mongoProductRepository.save(list);
            logger.info("*******************医药产品已全部同步缓存*******************");
        }
    }

    @Override
    public Product findOneFromCache(Long id) {
        return mongoProductRepository.findOne(id);
    }

    @Override
    public List<Product> findAllFromCache() {
        User user = RequestUtil.getLoginUser();
        return mongoProductRepository.findByAccountIdAndOrganIdAndDeleteFlag(user.getAccountId(), user.getOrganId(), 0);
    }

    @Override
    public List<Product> findAllBySmallClassIdFromCache(Long id) {
        return mongoProductRepository.findBySmallClassIdAndDeleteFlag(id, 0);
    }

    @Override
    public Result doSearchModel(Long id, int pageNumber, int pageSize, List<SearchModel> conditions) {
        User u = RequestUtil.getLoginUser();
        StringBuilder sql = new StringBuilder("select * from basic_product");
        sql.append(" where account_id = " + u.getAccountId());
        sql.append(" and small_class_id = " + id);
        sql.append(" and delete_flag = 0");
        for (SearchModel c : conditions) {
            String field = c.getField();
            String operate = c.getOperate();
            // 如果是推荐指数
            if ("recommend".equals(field)) {
                String[] values = c.getValues();
                if ("includ".equals(operate)) {
                    // 查找包含
                    for (int i = 0; i < values.length; i++) {
                        if (i == 0) {
                            sql.append(" and (find_in_set('" + values[i] + "'," + field + ")");
                        } else {
                            sql.append(" or find_in_set('" + values[i] + "'," + field + ")");
                        }
                    }
                    sql.append(")");
                } else if ("not includ".equals(operate)) {
                    // 查找不包含
                    for (String value : values) {
                        sql.append(" and " + field + " not like('%" + value + "%')");
                    }
                }
            } else {
                String value = c.getValue();
                if ("includ".equals(operate)) {
                    sql.append(" and " + field + " like('%" + value + "%')");
                } else if ("not includ".equals(operate)) {
                    sql.append(" and " + field + " not like('%" + value + "%')");
                }
            }
        }
        List<Product> l2 = new ArrayList<>();
        List<Product> l1 = sqlManager.execute(new SQLReady(sql.toString()), Product.class);
        int e = pageNumber * pageSize > l1.size() ? l1.size() : pageNumber * pageSize;
        int s = (pageNumber - 1) * pageSize;
        for (int i = s; i < e; i++) {
            l2.add(l1.get(i));
        }
        Map<String, Object> p = new HashMap<String, Object>(3);
        p.put("pageNumber", pageNumber);
        p.put("pageSize", pageSize);
        p.put("totalSize", l1.size());
        return ResultUtil.success(l2, p);
    }
}
